home *** CD-ROM | disk | FTP | other *** search
/ IRIS Performer 2.2 Friends Demo / SGI IRIS Performer 2.2 Friends Demo.iso / friends / medit / pfLoader / Internalstuff / convert.c next >
Text File  |  1997-11-20  |  6KB  |  222 lines

  1. /************************************************************************
  2. Check for Null-matrices
  3. ************************************************************************/
  4. void CheckMatrixForNull(pfMatrix mat) {
  5.  
  6.     int i, j;
  7.  
  8.     for (i=0; i<4; i++) {
  9.         for (j=0; j<4; j++) {
  10.         if (mat[i][j] ISNT 0.0) {
  11.         return;
  12.         }
  13.         }
  14.     }
  15.     pfMakeIdentMat(mat);
  16. }
  17. /************************************************************************
  18. Maintain a list of the objects we have already converted
  19. ************************************************************************/
  20. void AddToObjectList(Vars v, mwObjectPtr o, pfNode *data)
  21. {
  22.     if (v->NoObjects IS v->MaxObjects) {
  23.     v->MaxObjects += 100;
  24.     if (v->NoObjects IS 0) {
  25.         v->ObjectList = Allocate(v->MaxObjects*sizeof(ObjList));
  26.     }
  27.     else {
  28.         v->ObjectList = Reallocate(v->ObjectList, v->MaxObjects*sizeof(ObjList));
  29.     }
  30.     }
  31.     v->ObjectList[v->NoObjects].obj = o;
  32.     v->ObjectList[v->NoObjects].data = data;
  33.     v->NoObjects++;
  34. }
  35. static pfNode *FindObject(Vars v, mwObjectPtr o)
  36. {
  37.     reg int i;
  38.     for (i=0; i<v->NoObjects; i++) {
  39.     if (v->ObjectList[i].obj IS o) {
  40.         return v->ObjectList[i].data;
  41.     }
  42.     }
  43.     return NULL;
  44. }
  45. /************************************************************************
  46. Convert the file
  47. ************************************************************************/
  48. static void DoConvert(mwTreePtr tree, pfNode *parent, Vars v)
  49. {
  50.     reg int count;
  51.     reg float distance;
  52.     reg mwTreePtr next, a;
  53.  
  54.     reg pfDCS *dcs;
  55.     reg pfSCS *scs;
  56.     reg pfLOD *lod;
  57.     pfMatrix mat, inv;
  58.     reg pfGroup *group;
  59.     reg pfSwitch *Switch;
  60.     reg pfSequence *Sequence;
  61.     reg pfNode *obj, *newnode, *newparent, *namenode;
  62.  
  63.     while (tree) {
  64.     newnode = newparent = namenode = NULL;
  65.     next = tree->Down;
  66.     switch (tree->Type) {
  67.         case mwGroupBranch:        group = pfNewGroup();
  68.                     newnode = (pfNode*)group;
  69.                     tree->Converted = group;
  70.                     break;
  71.  
  72.         case mwPolygonBranch:    newnode = ConvertPolygonBranch(tree);
  73.                     tree->Converted = newnode;
  74.                     break;
  75.  
  76.         case mwLodBranch:        lod = pfNewLOD();
  77.                     pfAddChild(parent, lod);
  78.                     pfNodeName(lod, "Lod");
  79.  
  80.                     count = 0;
  81.                     distance = 0.0;
  82.                     while (tree) {
  83.                         group = pfNewGroup();
  84.                         tree->Converted = group;
  85.                         pfAddChild(lod, group);
  86.                         pfNodeName(group, tree->Name);
  87.                         pfLODRange(lod, count++, distance);
  88.                         DoConvert(tree->Across, (pfNode*)group, v);
  89.                         distance = tree->SwitchOut;
  90.                         tree = tree->Down;
  91.                     }
  92.                     pfLODRange(lod, count, distance);
  93.  
  94.                     next = NULL;
  95.                     newnode = NULL;
  96.                     break;
  97.  
  98.         case mwInstanceBranch:    ConvertMatrix(tree->Transformation, mat);
  99.                     scs = pfNewSCS(mat);
  100.                     newnode = (pfNode*)scs;
  101.                     if (obj = FindObject(v, tree->Obj)) {
  102.                         pfAddChild(newnode, pfClone(obj, 0));
  103.                     }
  104.                     else {
  105.                         DoConvert(tree->Obj->Tree, newnode, v);
  106.                         if (pfGetNumChildren(newnode) > 0) {
  107.                         AddToObjectList(v, tree->Obj, pfGetChild(newnode, 0));
  108.                         }
  109.                     }
  110.                     namenode = pfGetChild(scs, 0);
  111.                     tree->Converted = namenode;
  112.                     AddEngines(namenode, tree->Obj, FALSE);
  113.                     break;
  114.  
  115.         case mwSwitchBranch:    switch (tree->SubType) {
  116.                         case mwSwitchSequence:        Sequence = pfNewSeq();
  117.                                         newnode = (pfNode*)Sequence;
  118.                                         count = 0;
  119.                                         a = tree->Across;
  120.                                         while (a) {
  121.                                             count++;
  122.                                             a = a->Down;
  123.                                         }
  124.                                         if (count > 0) {
  125.                                             if (tree->SeqTime IS 0.0) {
  126.                                             pfSeqTime(Sequence, PFSEQ_ALL, 1.0/60.0);
  127.                                             }
  128.                                             else {
  129.                                             pfSeqTime(Sequence, PFSEQ_ALL, tree->SeqTime/count);
  130.                                             }
  131.                                             pfSeqInterval(Sequence, PFSEQ_CYCLE, 0, PFSEQ_ALL);
  132.                                             pfSeqDuration(Sequence, 1.0, PFSEQ_ALL);
  133.                                             pfSeqMode(Sequence, PFSEQ_START);                                        }
  134.                                         else {
  135.                                             NOTIFY"Warning: Sequence %s has no children)\n", tree->Name);
  136.                                         }
  137.                                         tree->Converted = Sequence;
  138.                                         break;
  139.  
  140.                         default:                Switch = pfNewSwitch();
  141.                                         newnode = (pfNode*)Switch;
  142.                                         tree->Converted = Switch;
  143.                                         break;
  144.                     }
  145.                     break;
  146.  
  147.         case mwDcsBranch:        dcs = pfNewDCS();
  148.                     newnode = (pfNode*)dcs;
  149.  
  150.                     /* Generate SCS -> DCS -> SCS */            
  151.                     ConvertMatrix(tree->DcsMatrix, mat);
  152.                     CheckMatrixForNull(mat);
  153.                     pfInvertFullMat(inv, mat);
  154.                     scs = pfNewSCS(mat);    pfNodeName(scs, "there");
  155.                     pfAddChild(parent, scs);
  156.                     pfAddChild(scs, dcs);
  157.                     scs = pfNewSCS(inv);    pfNodeName(scs, "back");
  158.  
  159.                     newparent = (pfNode*)dcs;
  160.                     newnode = (pfNode*)scs;
  161.                     namenode = (pfNode*)dcs;
  162.                     tree->Converted = dcs;
  163.                     break;
  164.  
  165.         default:            group = pfNewGroup();
  166.                     newnode = (pfNode*)group;
  167.                     tree->Converted = group;
  168.                     break;
  169.  
  170.     }
  171.     if (newnode) {
  172.         pfAddChild(((newparent)? newparent: parent), newnode);
  173.         if (tree->Name) {
  174.         pfNodeName(((namenode)? namenode: newnode), tree->Name);
  175.         }
  176.         if (tree->Across) {
  177.         DoConvert(tree->Across, newnode, v);
  178.         }
  179.     }
  180.     tree = next;
  181.     }
  182. }
  183. /************************************************************************
  184. Convert a model file to Performer Geometry
  185. ************************************************************************/
  186. pfNode *pfdConvertFrom_mw(mwFilePtr f)
  187. {
  188.     Vars v;
  189.     pfNode *root;
  190.     mwObjectPtr o;
  191.  
  192.     o = f->FirstObject;
  193.     if (o) {
  194.     while (o) {                /* Decide what to convert */
  195.         if (o->IsTopLevel) {
  196.         break;
  197.         }
  198.         o = o->Next;
  199.     }
  200.     if (!o) {
  201.         o = f->FirstObject;
  202.     }
  203.  
  204.     root = (pfNode*)pfNewGroup();        /* Create a root branch for the file */
  205.     pfNodeName(root, o->Name);
  206.  
  207.     v = NewConvertVars();            /* Convert it */
  208.     arena = pfGetSharedArena();
  209.     DoConvert(o->Tree, root, v);
  210.     AddEngines(root, o, TRUE);
  211.     FreeConvertVars(v);
  212.  
  213.     CleanDatabase(root);
  214.  
  215.     return root;
  216.     }
  217.     else {
  218.     NOTIFY"Nothing in model file!\n");
  219.     return NULL;
  220.     }
  221. }
  222.